package com.zjbbkj.baibai.common.utils.wanli;

import org.apache.commons.lang.StringUtils;

import java.io.*;
import java.lang.reflect.Type;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * MY工具类
 *
 * @program: boot-parent
 * @author: Mr.WanLi
 * @create: 2019-07-04 10:34
 **/

public class MyUtils {

    private static final String REGEX_MOBILE = "((\\+86|0086)?\\s*)((134[0-8]\\d{7})|(((13([0-3]|[5-9]))|(14[5-9])|15([0-3]|[5-9])|(16(2|[5-7]))|17([0-3]|[5-8])|18[0-9]|19(1|[8-9]))\\d{8})|(14(0|1|4)0\\d{7})|(1740([0-5]|[6-9]|[10-12])\\d{7}))";

    /**
     * 判空
     *
     * @param object
     * @return
     */
    public static Boolean isNull(Object object) {
        if (object == null || object.equals("")) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 升序排序
     *
     * @param map
     * @param <K>
     * @param <V>
     * @return
     */
    public static <K, V extends Comparable<? super V>> Map<K, V> sortByValueAscending(Map<K, V> map) {
        List<Map.Entry<K, V>> list = new LinkedList<>(map.entrySet());
        Collections.sort(list, (o1, o2) -> {
            int compare = (o1.getValue()).compareTo(o2.getValue());
            return compare;
        });

        Map<K, V> result = new LinkedHashMap<>();
        for (Map.Entry<K, V> entry : list) {
            result.put(entry.getKey(), entry.getValue());
        }
        return result;
    }

    /**
     * 降序排序
     *
     * @param map
     * @param <K>
     * @param <V>
     * @return
     */
    //
    public static <K, V extends Comparable<? super V>> Map<K, V> sortByValueDescending(Map<K, V> map) {
        List<Map.Entry<K, V>> list = new LinkedList<>(map.entrySet());
        Collections.sort(list, (o1, o2) -> {
            int compare = (o1.getValue()).compareTo(o2.getValue());
            return -compare;
        });

        Map<K, V> result = new LinkedHashMap<>();
        for (Map.Entry<K, V> entry : list) {
            result.put(entry.getKey(), entry.getValue());
        }
        return result;
    }


    /**
     * 获取map中第一个key值
     *
     * @param map 数据源
     * @return
     */
    public static String getKeyOrNull(Map<String, String> map) {
        String obj = null;
        for (Map.Entry<String, String> entry : map.entrySet()) {
            obj = entry.getKey();
            if (obj != null) {
                break;
            }
        }
        return obj;
    }


    /**
     * 获取map中第一个数据值
     *
     * @param map 数据源
     * @return
     */
    private static Object getFirstOrNull(Map<String, Object> map) {
        Object obj = null;
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            obj = entry.getValue();
            if (obj != null) {
                break;
            }
        }
        return obj;
    }


    /**
     * 获取不重复的随机数
     *
     * @param num 个数
     * @return
     */
    public static int[] getRandomNumber(int num) {
        boolean[] bool = new boolean[14];
        int randInt = 0;
        int[] number = new int[num];
        for (int j = 0; j < num; j++) {
            /**得到10个不同的随机数*/
            do {
                randInt = (int) (Math.random() * 10 + 3);
            } while (bool[randInt]);
            bool[randInt] = true;
            number[j] = randInt;
            System.out.println(randInt);
        }
        return number;
    }

    /**
     * 根据map获取KEY
     *
     * @param map
     * @param value
     * @return
     */
    private static String getKey(Map<Object, Object> map, String value) {
        String key = "";
        for (Map.Entry<Object, Object> entry : map.entrySet()) {
            if (value.equals(entry.getValue())) {
                key = entry.getKey().toString();
            }
        }
        return key;
    }

    /*public static Boolean isExist(Map<Object,Object> map,String key){
        for (Map.Entry<Object, Object> entry : map.entrySet()){

        }
        return
    }*/

    public static void testMap() {
        Map<Object, Object> map = new LinkedHashMap<>();
        for (Map.Entry<Object, Object> entry : map.entrySet()) {
            System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());
        }
    }


    /**
     * 判断是否是手机号
     *
     * @param tel 手机号
     * @return boolean true:是  false:否
     */
    public static boolean isMobile(String tel) {
        if (StringUtils.isEmpty(tel)) {
            return false;
        }
        return Pattern.matches(REGEX_MOBILE, tel);
    }

    //读取文件
    public static String readTxt(File file) throws IOException {
        String s = "";
        InputStreamReader in = new InputStreamReader(new FileInputStream(file), "UTF-8");
        BufferedReader br = new BufferedReader(in);
        StringBuffer content = new StringBuffer();
        while ((s = br.readLine()) != null) {
            content = content.append(s);
        }
        return content.toString();
    }

    public static boolean isGb2312(String str) {
        if (null == str) return false;
        if (str.trim() == " ") return false;
        byte[] bytes = str.getBytes();
        if (bytes.length < 2)
            return false;
        byte aa = (byte) 0xB0;
        byte bb = (byte) 0xF7;
        byte cc = (byte) 0xA1;
        byte dd = (byte) 0xFE;
        if (bytes[0] >= aa && bytes[0] <= bb) { //高字节
            if (bytes[1] < cc || bytes[1] > dd) { //低字节
                return false;
            }
            return true;
        }
        return false;
    }

    public static String strTo16(String s) {
        String str = "";
        for (int i = 0; i < s.length(); i++) {
            String c = String.valueOf(s.charAt(i));
            /*boolean check = check(c);
            boolean checkNum = checkNum(c);
            boolean containSpace = containSpace(c);*/
            boolean ascll = isAscll(c);
            int ch = (int) s.charAt(i);
            String s4 = Integer.toHexString(ch);
            if (ascll) {
                s4 = "00" + s4;
            }
            str = str + s4;
        }
        return str;
    }

    public static boolean isAscll(String str) {
        Pattern p = Pattern.compile("[\u0000-\u007F]");
        Matcher m = p.matcher(str);
        if (m.find()) {
            return true;
        }
        return false;
    }

    /**
     * 判断是否为标点符号
     *
     * @param s
     * @return
     */
    public static boolean check(String s) {
        boolean b = false;
        String tmp = s;
        tmp = tmp.replaceAll("\\p{P}", "");
        if (s.length() != tmp.length()) {
            b = true;
        }
        return b;
    }

    /**
     * 判断是否为数字
     *
     * @param s
     * @return
     */
    public static boolean checkNum(String s) {
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        return pattern.matcher(s).matches();
    }

    /**
     * 判断字符串中是否包含中文
     *
     * @param str 待校验字符串
     * @return 是否为中文
     * @warn 不能校验是否为中文标点符号
     */
    public static boolean isContainChinese(String str) {
        Pattern p = Pattern.compile("[\u4e00-\u9fef]");
        Matcher m = p.matcher(str);
        if (m.find()) {
            return true;
        }
        return false;
    }

    /**
     * 验证是否字符串包含空格
     *
     * @param phone 需要字符串
     * @return 不包含返回true 包含返回false
     * @author 孙磊
     * @version 1.0
     * @time 2016-12-30
     * @status 正常
     */
    public static boolean containSpace(String phone) {
        Pattern pattern = Pattern.compile("[0-9a-zA-Z\u4E00-\u9FA5]+");
        Matcher matcher = pattern.matcher(phone);
        return matcher.matches();
    }


    public static String hexStr2Str(String hex) {
        String hexStr = "";
        String str = "0123456789ABCDEF"; //16进制能用到的所有字符 0-15
        for(int i=0;i<hex.length();i++){
            String s = hex.substring(i, i+1);
            if(s.equals("a")||s.equals("b")||s.equals("c")||s.equals("d")||s.equals("e")||s.equals("f")){
                s=s.toUpperCase().substring(0, 1);
            }
            hexStr+=s;
        }

        char[] hexs = hexStr.toCharArray();//toCharArray() 方法将字符串转换为字符数组。
        int length = (hexStr.length() / 2);//1个byte数值 -> 两个16进制字符
        byte[] bytes = new byte[length];
        int n;
        for (int i = 0; i < bytes.length; i++) {
            int position = i * 2;//两个16进制字符 -> 1个byte数值
            n = str.indexOf(hexs[position]) * 16;
            n += str.indexOf(hexs[position + 1]);
            // 保持二进制补码的一致性 因为byte类型字符是8bit的  而int为32bit 会自动补齐高位1  所以与上0xFF之后可以保持高位一致性
            //当byte要转化为int的时候，高的24位必然会补1，这样，其二进制补码其实已经不一致了，&0xff可以将高的24位置为0，低8位保持原样，这样做的目的就是为了保证二进制数据的一致性。
            bytes[i] = (byte) (n & 0xff);
        }
        String name = "";
        try {
            name = new String(bytes,"UNICODE");
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return name;
    }

    public static Map getPortsStatusMap(Integer deviceType){
        Map<String,Integer> map = new LinkedHashMap<>();
        for (int i = 0 ; i < deviceType ; i++){
            map.put(String.valueOf(i),0);
        }
        return map;
    }

    public static String ports(Set set){
        String resultPorts = "";
        resultPorts = StringUtils.join(set.toArray(), ",");
        return resultPorts;
    }

    //数组拼接成字符串
    public static String ArrayToString(String[] string){
        String str1=StringUtils.join(string, ",");
        return str1;
    }

}
